package com.lagou.tomcatserver;

import com.lagou.tomcatapi.HttpServlet;
import com.lagou.tomcatapi.RequestProcessor;
import com.lagou.tomcatapi.WebServlet;

import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.net.*;
import java.util.*;
import java.util.concurrent.*;
import java.util.jar.JarEntry;
import java.util.jar.JarFile;

/**
 * Minicat的主类
 */
public class Bootstrap {

    /**定义socket监听的端口号*/
    private int port = 8080;

    public int getPort() {
        return port;
    }

    public void setPort(int port) {
        this.port = port;
    }


    /**
     * Minicat启动需要初始化展开的一些操作
     */
    public void start() throws Exception {

        // 加载解析相关的配置，web.xml
        loadServlet();


        // 定义一个线程池
        int corePoolSize = 10;
        int maximumPoolSize =50;
        long keepAliveTime = 100L;
        TimeUnit unit = TimeUnit.SECONDS;
        BlockingQueue<Runnable> workQueue = new ArrayBlockingQueue<>(50);
        ThreadFactory threadFactory = Executors.defaultThreadFactory();
        RejectedExecutionHandler handler = new ThreadPoolExecutor.AbortPolicy();


        ThreadPoolExecutor threadPoolExecutor = new ThreadPoolExecutor(
                corePoolSize,
                maximumPoolSize,
                keepAliveTime,
                unit,
                workQueue,
                threadFactory,
                handler
        );


        ServerSocket serverSocket = new ServerSocket(port);
        System.out.println("=====>>>Minicat start on port：" + port);


        System.out.println("=========>>>>>>使用线程池进行多线程改造");

        while(true) {

            Socket socket = serverSocket.accept();
            RequestProcessor requestProcessor = new RequestProcessor(socket,servletMap);
            //requestProcessor.start();
            threadPoolExecutor.execute(requestProcessor);
        }

    }


    private Map<String, HttpServlet> servletMap = new HashMap<String,HttpServlet>();

    private void loadServlet()
        throws IOException, ClassNotFoundException, IllegalAccessException, InstantiationException {
        String path="E:\\拉勾";//webapp所在目录
        File file=new File(path);
        File[] files = file.listFiles();
        List<String> jarPaths=new ArrayList<>();
        List<URL> urlList=new ArrayList<>();
        for(File f: files)
        {
            if(f.getName().endsWith(".jar"))
            {
                jarPaths.add(f.getName());
                urlList.add(new URL("file:"+f.getName()));
            }
        }
        URLClassLoader urlClassLoader = new URLClassLoader((URL[])urlList.toArray());

        for(String filename: jarPaths)
        {
            JarFile jarFile=new JarFile(filename);
            Enumeration<JarEntry> entries = jarFile.entries();
            while (entries.hasMoreElements()) {
                JarEntry jarEntry = entries.nextElement();
                String name = jarEntry.getName();
                if (name != null && name.endsWith(".class")) {
                    Class<?> c =
                        urlClassLoader.loadClass(name.replace("/", ".").substring(0, name.length() - 6));
                    if(c.isAnnotationPresent(WebServlet.class))
                    {
                        WebServlet annotation = c.getAnnotation(WebServlet.class);
                        String url = annotation.url();
                        this.servletMap.put(url,(HttpServlet)c.newInstance());
                    }
                }
            }
        }

    }


    /**
     * Minicat 的程序启动入口
     * @param args
     */
    public static void main(String[] args) {
        Bootstrap bootstrap = new Bootstrap();
        try {
            // 启动Minicat
            bootstrap.start();
        } catch (IOException e) {
            e.printStackTrace();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}
